var GAME_HEIGHT = 400;
var GAME_WIDTH = 400;
var GAME_HALF_HEIGHT = Math.floor(GAME_HEIGHT/2);
var GAME_HALF_WIDTH = Math.floor(GAME_WIDTH/2);
/*----------- Stage -----------*/
function Stage(canvas) {
    this.canvas = canvas;
    this.currentTime = 0;
    this.targetFps = 40;
    this.targetInterval = Math.round(1000 /  this.targetFps);
    this.scenes = [];
    this.currentScene = -1;
    this.frameCount = 0;
    this.fps = 0;
    this.delta = 0;
    this.timer = null;
    this.fpsTimer = null;

    if (this.canvas.getContext) {
        this.context = this.canvas.getContext('2d');
    } else {
        alert('This requires a browser that supports the <canvas> tag!');
    }

    var self = this;
    this.canvas.addEventListener('click', function(e) {
        var pos = getCursorPos(e, self.canvas);
        var currScene = self.scenes[self.currentScene];
        if (currScene.click) {
            currScene.click(pos.x, pos.y);
        }
    }, false);

    this.canvas.addEventListener('dblclick', function(e) {
        var pos = getCursorPos(e, self.canvas);
        var currScene = self.scenes[self.currentScene];
        if (currScene.dblclick) {
            currScene.dblclick(pos.x, pos.y);
        }
    }, false);
    
    this.canvas.addEventListener('mousemove', function(e) {
        var pos = getCursorPos(e, self.canvas);
        var currScene = self.scenes[self.currentScene];
        if (currScene.mousemove) {
            currScene.mousemove(pos.x, pos.y);
        }
    }, false);
    
    window.addEventListener('keydown', function(e){
        var currScene = self.scenes[self.currentScene];
        if (currScene.keydown) {
            currScene.keydown(e);
        }
    });
    
    window.addEventListener('keyup', function(e){
        var currScene = self.scenes[self.currentScene];
        if (currScene.keyup) {
            currScene.keyup(e);
        }
    });
        
    $(document).blur(function(){
        self.pause();
    }).focus(function(){
        self.start();
    });
        
//    $(window).blur(function(){
//        self.pause();
//    }).focus(function(){
//        self.start();
//    });
}

Stage.prototype.start = function() {

    if (!this.scenes[this.currentScene]) {
        alert('No current scene');
        return;
    }
	
    this.context.fillStyle = "#000000";
    this.context.strokeStyle = "#000000";
    this.context.font = "12px Courier New";
    
    this.currentTime = Date.now();
    var self = this;
    this.timer = setInterval(function() {
        var delta = Date.now() - self.currentTime;
        self.currentTime = Date.now();
        self.delta = delta;
        self.update(delta);
        self.render();
    }, this.targetInterval);
    
    this.fpsTimer = setInterval(function() {
        self.fps = self.frameCount;
        self.frameCount = 0;
    }, 1000);
};

Stage.prototype.pause = function(scene) {
    clearInterval(this.timer);
    clearInterval(this.fpsTimer);
};

Stage.prototype.addScene = function(scene) {
    this.scenes.push(scene);
};

Stage.prototype.setCurrentScene = function(index) {
    this.currentScene = index;
    this.scenes[index].init();
};

Stage.prototype.update = function(delta){
    this.scenes[this.currentScene].update(delta);
}

Stage.prototype.render = function() {
   
    this.frameCount++;
    var ctx = this.context;
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    
    this.scenes[this.currentScene].render(ctx);
    
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.fillText("fps: " + this.fps, 2, 10);
    ctx.fillText("delta: " + this.delta, 2, 20);
    ctx.fillText("cursor: " + cursor.x + " " + cursor.y , 2, 30);
    ctx.fillText("mychar: " + mychar.x + " " + mychar.y, 2, 40);
    ctx.fillText("dist: " + dist, 2, 50);
};

/*----------- end Stage -----------*/

/*----------- utilities -----------*/
function getCursorPos(e, elem) {
    var x;
    var y;
    if (e.pageX || e.pageY) {
        x = e.pageX - elem.offsetLeft;
        y = e.pageY - elem.offsetTop;
    } else {
        x = e.clientX + document.body.scrollLeft
        + document.documentElement.scrollLeft - elem.offsetLeft;
        y = e.clientY + document.body.scrollTop
        + document.documentElement.scrollTop - elem.offsetTop;
    }
    return {
        x : x,
        y : y
    };
}
/*----------- end utilities -----------*/
/*----------- AnimatedSprite -----------*/
function AnimatedSprite(image, options) {
    this.image = image;
    this.cellWidth = options.cellWidth;
    this.cellHeight = options.cellHeight;
    this.x = 0;
    this.y = 0;
    this.offsetX = options.offsetX;
    this.offsetY = options.offsetY;
    this.frames = options.frames;
    this.gridSpace = 0;
    this.timer = -1;
    this.interval = options.interval;
    this.visible = true;
    
    if(options.gridSpace !== undefined){
        this.gridSpace = options.gridSpace;
    }

    var len = options.frames.length;
    for ( var i = 0; i < len; i++) {
        this.frames[i].x = options.frames[i].x * (options.cellWidth + this.gridSpace);
        this.frames[i].y = options.frames[i].y * (options.cellHeight + this.gridSpace);
    }
    
    this.cellX = this.frames[0].x;
    this.cellY = this.frames[0].y;
}

AnimatedSprite.prototype.playOnce = function(){
    var index = 0;
    var self = this;
    var frames = this.frames;
    var len = this.frames.length;
    
    if(this.timer === -1){
        this.timer = setInterval(function() {
            self.cellX = frames[index].x;
            self.cellY = frames[index].y;
            index++;
            if (index >= len) {
                clearInterval(self.timer);
                self.timer = -1;
                if(self.onPlayEnd !== undefined){
                    self.onPlayEnd();
                }
            }
        }, this.interval);
    }
}

AnimatedSprite.prototype.playLoop = function(){
    var index = 0;
    var self = this;
    var frames = this.frames;
    var len = this.frames.length;
    
    this.timer = setInterval(function() {
        self.cellX = frames[index].x;
        self.cellY = frames[index].y;
        index++;
        if (index >= len) {
            index = 0;
        }
    }, this.interval);
}

AnimatedSprite.prototype.stop = function(){
    clearInterval(this.timer);
    this.timer = 0;
};

AnimatedSprite.prototype.render = function(context) {
    if(this.visible){
        context.drawImage(this.image, this.cellX, this.cellY, this.cellWidth,
            this.cellHeight, this.x - this.offsetX, this.y - this.offsetY,
            this.cellWidth, this.cellHeight); 
    }
};
/*----------- end AnimatedSprite -----------*/

/*----------- ImageSprite -----------*/
function ImageSprite(image, options) {
    this.image = image;
    this.x = 0;
    this.y = 0;
    this.visible = true;
    this.render = function(context) {
    };

    if (options == null) {
        this.render = function(context) {
            context.drawImage(this.image, this.x, this.y);
        };
    } else {
        var offsetX = options.offsetX;
        var offsetY = options.offsetY;
        this.cellWidth = options.cellWidth;
        this.cellHeight = options.cellHeight;
        this.cellX = options.x * this.cellWidth;
        this.cellY = options.y * this.cellHeight;

        this.render = function(context) {
            if(this.visible){
                context.drawImage(this.image, this.cellX, this.cellY,
                    this.cellWidth, this.cellHeight, this.x - offsetX, this.y
                    - offsetY, this.cellWidth, this.cellHeight);
            }
        };
    }
}

/*----------- end ImageSprite -----------*/

/*----------- Unit -----------*/
function Unit(id, x, y, name) {
    this.id = id;
    this.name = name;
    this.x = x;
    this.y = y;
    this.nameOffsetX = 0;
    this.nameOffsetY = 0;
    this.cursorOffsetX = 0;
    this.cursorOffsetY = 0;
    this.cursorBoundsX = 0;
    this.cursorBoundsY = 0;
    this.speed = 0.1;
    this.sprites = [];
    this.destX = x + 0.2;
    this.destY = y + 0.2;
    this.focus = false;
    this.spriteIndex = Unit.STAND_DOWN;
    this.lastState =   Unit.STAND_DOWN;
    this.target = null;
    this.active = true;
    this.visible = true;
}

Unit.MOVE_UP = 0;
Unit.MOVE_RIGHT = 1;
Unit.MOVE_DOWN = 2;
Unit.MOVE_LEFT = 3;
Unit.STAND_UP = 4;
Unit.STAND_RIGHT = 5;
Unit.STAND_DOWN = 6;
Unit.STAND_LEFT = 7;
Unit.ATK_LEFT = 8;
Unit.ATK_RIGHT = 9;
Unit.DIE = 10;

Unit.prototype.update = function(delta) {

    if(this.active){
        var destX = this.destX;
        var destY = this.destY;
        var speed = this.speed;
        var x = this.x;
        var y = this.y;
        var deltaX = destX - x;
        var deltaY = destY - y;
        
        if ((Math.abs(deltaX) + Math.abs(deltaY)) > 2.0) {
            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                if (deltaX < 0) {
                    this.spriteIndex = Unit.MOVE_LEFT;
                } else {
                    this.spriteIndex = Unit.MOVE_RIGHT;
                }
            } else {
                if (deltaY < 0) {
                    this.spriteIndex = Unit.MOVE_UP;
                } else {
                    this.spriteIndex = Unit.MOVE_DOWN;
                }
            }
            var theta = Math.atan2(destX - x, destY - y);
            this.x += (speed * Math.sin(theta) * delta);
            this.y += (speed * Math.cos(theta) * delta);
        } else {
            if (this.lastState < Unit.STAND_UP) {
                this.spriteIndex = this.lastState + 4;
            }
        }
    
        if(this.target){
        
        }
       
    }
     
    this.sprites[this.spriteIndex].x = this.x;
    this.sprites[this.spriteIndex].y = this.y;   
        
    if (this.spriteIndex != this.lastState)
        this.lastState = this.spriteIndex;

}

Unit.prototype.render = function(ctx) {
    if(this.visible){
        var centerX = this.x;
        var centerY = this.y;
        var width = 40;
        var height = 15;
    
        if(this.focus){
            ctx.beginPath();
            ctx.moveTo(centerX, centerY - height/2); // A1
            ctx.bezierCurveTo(
                centerX + width/2, centerY - height/2, // C1
                centerX + width/2, centerY + height/2, // C2
                centerX, centerY + height/2); // A2
            ctx.bezierCurveTo(
                centerX - width/2, centerY + height/2, // C3
                centerX - width/2, centerY - height/2, // C4
                centerX, centerY - height/2); // A1
            ctx.closePath();
            ctx.strokeStyle = '#00FF00';
            ctx.stroke();
            ctx.strokeStyle = '#000000';
        }
    
        this.sprites[this.spriteIndex].render(ctx);
    
        //draw name
        ctx.fillStyle = "#000000";
        ctx.fillText(this.name, centerX - this.nameOffsetX, centerY - this.nameOffsetY);
    }
};

Unit.prototype.addSprite = function(state, sprite) {
    this.sprites[state] = sprite;
};

Unit.prototype.moveTo = function(x, y) {
    this.destX = x;
    this.destY = y;
    this.target = null;
};

Unit.prototype.attack = function(target){

    if(target.x > this.x){
        this.spriteIndex = Unit.ATK_RIGHT;
        this.sprites[this.spriteIndex].playOnce();
        target.die();
    }else{
        this.spriteIndex = Unit.ATK_LEFT;
        this.sprites[this.spriteIndex].playOnce();
        target.die();
    }
};

Unit.prototype.die = function(){
    if(this.active){
        this.active = false;
        this.spriteIndex = Unit.DIE;
        this.sprites[this.spriteIndex].playOnce();
        var self = this;
        this.sprites[this.spriteIndex].onPlayEnd = function(){
            self.visible = false;
        };
    }
};
/*----------- end Unit -----------*/
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
    var rest = this.slice((to || from) + 1 || this.length);
    this.length = from < 0 ? this.length + from : from;
    return this.push.apply(this, rest);
};
